package com.orange.hdfs.utils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.log4j.Logger;

import com.orange.utils.TimeUtils;

public class HDFSUtils {

	private static final Logger logger = Logger.getLogger(HDFSUtils.class);
	
	/**
	 * 判断文件是否存在
	 * @param path
	 * @return
	 */
	public static boolean checkFileExits(FileSystem fs, String path) {
		boolean result = false;
		try {
			result = fs.exists(new Path(path));
//			fs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 判断是否为文件夹
	 * @param path
	 * @return
	 */
	public static boolean isDirectory(FileSystem fs, String path) {
		boolean result = false;
		try {
			result = fs.isDirectory(new Path(path));
//			fs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 删除文件或目录
	 * @param hdfsPath
	 * @throws IOException
	 */
	public static void delFile(FileSystem fs, String hdfsPath) throws IOException {
		fs.delete(new Path(hdfsPath), true);
		logger.info("文件:" + hdfsPath + "已删除!");
//		fs.close();
	}

	/**
	 * 获取目录下所有文件清单
	 * @param path
	 * @return
	 */
	public static List<String> listAllFile(FileSystem fs, String path) {
		List<String> names = new ArrayList<String>();
		try {
			FileStatus[] stats = fs.listStatus(new Path(path));
			for (int i = 0; i < stats.length; ++i) {
				if (stats[i].isFile()) {
					names.add(stats[i].getPath().toString());
				}
			}
//			fs.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return names;
	}

	/**
	 * 获取目录下所有过期文件
	 * @param path
	 * @return
	 */
	public static List<String> listAllExpireFile(FileSystem fs, String path, int expireTime) {
		List<String> names = new ArrayList<String>();
		try {
			FileStatus[] stats = fs.listStatus(new Path(path));
			for (int i = 0; i < stats.length; ++i) {
				if (stats[i].isFile()
						&& TimeUtils.ifGreaterSpeHourWithNow(stats[i].getModificationTime(), expireTime)) {
					names.add(stats[i].getPath().toString());
				}
			}
//			fs.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return names;
	}

	/**
	 * 获取指定目录下所有过期文件（非递归，不包含目录）
	 * @param path
	 * @param expireTime
	 * @return
	 */
	public static List<String> listAllExipreFilesWithNoRecursion(FileSystem fs, String path, int expireTime) {
		List<String> names = new ArrayList<String>();
		RemoteIterator<LocatedFileStatus> remoteIterator;
		try {
			remoteIterator = fs.listFiles(new Path(path), false);
			while (remoteIterator.hasNext()) {
				LocatedFileStatus locatedFileStatu = remoteIterator.next();
				// 判断文件是否过期
				if (TimeUtils.ifGreaterSpeHourWithNow(locatedFileStatu.getModificationTime(), expireTime)) {
					names.add(locatedFileStatu.getPath().toString());
				}
			}
//			fs.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return names;
	}

	/**
	 * 获取指定目录下所有过期文件（递归获取，但不包含目录）
	 * @param path
	 * @param expireTime
	 * @return
	 */
	public static List<String> listAllExipreFilesWithRecursion(FileSystem fs, String path, int expireTime) {
		List<String> names = new ArrayList<String>();
		RemoteIterator<LocatedFileStatus> remoteIterator;
		try {
			remoteIterator = fs.listFiles(new Path(path), true);
			while (remoteIterator.hasNext()) {
				LocatedFileStatus locatedFileStatu = remoteIterator.next();
				// 判断文件是否过期
				if (TimeUtils.ifGreaterSpeHourWithNow(locatedFileStatu.getModificationTime(), expireTime)) {
					names.add(locatedFileStatu.getPath().toString());
				}
			}
//			fs.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return names;
	}

	/**
	 * 获取目录下所有文件列表（包括文件、目录、链接）
	 * @param path
	 * @return
	 */
	public static List<String> listAll(FileSystem fs, String path) {
		List<String> names = new ArrayList<String>();
		try {
			FileStatus[] stats = fs.listStatus(new Path(path));
			for (int i = 0; i < stats.length; ++i) {
				if (stats[i].isFile()) {
					// regular file
					names.add(stats[i].getPath().toString());
				} else if (stats[i].isDirectory()) {
					// dir
					names.add(stats[i].getPath().toString());
				} else if (stats[i].isSymlink()) {
					// is s symlink in linux
					names.add(stats[i].getPath().toString());
				}
			}
//			fs.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return names;
	}
}
